#include "TpPlugin.h"
#include "Log.h"
#include "Expand/PluginsManager.h"
#include "Game/IInventory.hpp"
#include "Managers/GameManager.h"
#include "Components/ComponentInventory.h"
#include "Components/ComponentPlayer.h"
#include "Components/ComponentBody.h"

#include "Network/Client.h"
#include "Player/PlayerData.h"

#include "Subsystems/SubsystemPlayers.h"

#include "GameSingleton.h"

namespace PocketSurvival
{
    static const std::string titleText = "传送";
    constexpr const char *help1 = "\n"
                                  "/tp (玩家)    -传送到对应的玩家位置上\n"
                                  "/tp (玩家1) (玩家2)    -将玩家1传送到玩家2的位置上\n"                                  
                                  "/tp (X) (Y) (Z)    -传送到对应的位置上\n"
                                  "/tp (玩家) (X) (Y) (Z)    -将对应玩家传送到对应位置上\n";

    static const std::string helpStr = help1;

    const std::string &TpPlugin::getPluginName()
    {
        static const std::string pluginName = "传送插件";
        return pluginName;
    }

    const std::string &TpPlugin::getIntroduce()
    {
        static const std::string introduce = "\n/tp help - 查看传送指令帮助";
        return introduce;
    }

    uint32_t TpPlugin::getUseAuthLevel()
    {
        return 100;
    }

    AuthDisplayType TpPlugin::getDisplayType()
    {
        return AuthDisplayType::Authority;
    }

    void TpPlugin::processCmd(ChatObj &chatObj, std::vector<std::string> &cmdDataVec)
    {
        if (cmdDataVec.size() == 2)
        {
            if(chatObj.m_isTerminal == true)
            {
                chatObj.sendMessage(titleText, "控制台不能使用");
                return;
            }
            std::vector<std::shared_ptr<PlayerData>> playerVec;
            m_subsystemPlayers->getPlayerDataByName(cmdDataVec[1], playerVec);

            if(playerVec.size() == 0)
            {
                chatObj.sendMessage(titleText, fmt::format("玩家 {} 貌似不在线", cmdDataVec[1]));
            }
            else if (playerVec.size() == 1)
            {
                Vector3 position;
                playerVec[0]->componentPlayer->componentBody->getPosition(position);
                chatObj.m_client->playerData->componentPlayer->setNetPosition(position);
                chatObj.sendMessage(titleText, fmt::format("成功传送到玩家 {} 的位置： {}", cmdDataVec[1], position.toString()));
            }
            else if (playerVec.size() > 1)
            {
                chatObj.sendMessage(titleText, fmt::format("有多个名字为 {} 的玩家，无法进行传送", cmdDataVec[1]));
            }
            return;
        }
        else if (cmdDataVec.size() == 3)
        {
            std::vector<std::shared_ptr<PlayerData>> playerVec1;
            std::vector<std::shared_ptr<PlayerData>> playerVec2;
            m_subsystemPlayers->getPlayerDataByName(cmdDataVec[1], playerVec1);
            m_subsystemPlayers->getPlayerDataByName(cmdDataVec[2], playerVec2);

            if (playerVec1.size() == 1 && playerVec2.size() == 1)
            {
                Vector3 position;
                playerVec2[0]->componentPlayer->componentBody->getPosition(position);
                playerVec1[1]->componentPlayer->setNetPosition(position);
                chatObj.sendMessage(titleText, fmt::format("成功将玩家 {} 传送到玩家 {} 的位置({})上", cmdDataVec[1], cmdDataVec[2], position.toString()));
            }
            else
            {
                chatObj.sendMessage(titleText, "传送失败");
            }
            return;
        }
        else if (cmdDataVec.size() == 4)
        {
            if(chatObj.m_isTerminal == true)
            {
                chatObj.sendMessage(titleText, "控制台不能使用");
                return;
            }
            Vector3 position;
            position.posX = strtof(cmdDataVec[1].c_str(), NULL);
            position.posY = strtof(cmdDataVec[2].c_str(), NULL);
            position.posZ = strtof(cmdDataVec[3].c_str(), NULL);

            if (std::isnan(position.posX) || std::isnan(position.posY) || std::isnan(position.posZ))
            {
                chatObj.sendMessage(titleText, "位置数据错误");
                return;
            }

            chatObj.m_client->playerData->componentPlayer->setNetPosition(position);
            chatObj.sendMessage(titleText, fmt::format("成功传送位置： {}", position.toString()));
            return;
        }
        else if (cmdDataVec.size() == 5)
        {
            std::vector<std::shared_ptr<PlayerData>> playerVec;
            m_subsystemPlayers->getPlayerDataByName(cmdDataVec[1], playerVec);

            if(playerVec.size() == 0)
            {
                chatObj.sendMessage(titleText, fmt::format("玩家 {} 貌似不在线", cmdDataVec[1]));
            }
            else
            {
                Vector3 position;
                position.posX = strtof(cmdDataVec[2].c_str(), NULL);
                position.posY = strtof(cmdDataVec[3].c_str(), NULL);
                position.posZ = strtof(cmdDataVec[4].c_str(), NULL);
                if (std::isnan(position.posX) || std::isnan(position.posY) || std::isnan(position.posZ))
                {
                    chatObj.sendMessage(titleText, "位置数据错误");
                    return;
                }
                for (auto &playerData : playerVec)
                {
                    playerData->componentPlayer->setNetPosition(position);
                }
                chatObj.sendMessage(titleText, fmt::format("成功将所有玩家名为 {} 的玩家传送到位置： {}", cmdDataVec[1], position.toString()));
            }
            return;
        }

        chatObj.sendMessage(titleText, helpStr);
    }

    void TpPlugin::getCmds(std::vector<std::string> &cmdVec)
    {
        cmdVec.push_back("/tp");
    }

    void TpPlugin::load()
    {
        m_subsystemPlayers = GameSingleton::singletonPtr->getSingleton<SubsystemPlayers>();
    }

} // namespace PocketSurvival


using namespace PocketSurvival;

extern "C" void initialize()
{
    GameSingleton::singletonPtr->getSingleton<PluginsManager>()->registerPlugin<TpPlugin>();
    Log::Info("成功加载 TpPlugin 插件");
}